package fr.resasante.spring3.security;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.naming.NamingException;

import org.apache.commons.beanutils.BeanUtils;
import org.jboss.logging.Logger;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import fr.resasante.ejb.dto.User;
import fr.resasante.ejb.dto.UserRole;
import fr.resasante.ejb.service.UserServiceRemote;
import fr.resasante.exception.ApplicationException;
import fr.resasante.utils.CommonUtils;
import fr.resasante.utils.ServicesUtils;

/**
 * Class overriding the Spring security for displaying login pages
 * 
 * @author GEFFROY-DE-VILLEBLAN
 * 
 */
public class UserServiceImpl implements UserDetailsService {
	/**
	 * Logger for the class
	 */
	private static final Logger logger = Logger.getLogger(UserServiceImpl.class.getName());

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.security.core.userdetails.UserDetailsService#
	 * loadUserByUsername(java.lang.String)
	 */
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

		UserServiceRemote service = null;
		User user = null;
		try {
			service = (UserServiceRemote) ServicesUtils.getInstance().callService(
					"UserService");
			user = service.getUserByUsername(username);
			if (null == user) {
				throw new UsernameNotFoundException("User not found: " + username);
			}
		} catch (final NamingException e) {
			logger.error(CommonUtils.getInstance().getStackTrace(e));
			throw new UsernameNotFoundException("User not found: " + username);
		}
		final List<GrantedAuthority> Authorities = new ArrayList<GrantedAuthority>();
		final Iterator<UserRole> rolesIterator = user.getUserRoles().iterator();
		while (rolesIterator.hasNext()) {
			final UserRole userRole = rolesIterator.next();
			Authorities.add(new SimpleGrantedAuthority(userRole.getAuthority()));
		}
		final UserImpl userImpl = new UserImpl(username, user.getPassword(), Authorities);
		try {
			BeanUtils.copyProperties(userImpl, user);
		} catch (final Exception e) {
			throw new ApplicationException(
					"Unable to copy properties to the spring session user", e);
		}
		return userImpl;
	}
}
